using System;
using System.IO;
using SevenZip;
using SevenZip.Compression.LZMA;
using SevenZSharp.Engines;

namespace SevenZSharp.Encoders
{
   /// <summary>
   /// 
   /// </summary>
   public class LzmaEncoder : ShellEncoder
   {
      /// <summary>
      /// 
      /// </summary>
      /// <param name="engine"></param>
      public LzmaEncoder(ShellEngine engine)
         : base(engine)
      {
      }

      /// <summary>
      /// 
      /// </summary>
      /// <param name="inFile"></param>
      /// <param name="outFile"></param>
      public override void EncodeSingleFile(string inFile, string outFile)
      {
         using (FileStream inStream = new FileStream(inFile, FileMode.Open, FileAccess.Read))
         {
            using (FileStream outStream = new FileStream(outFile, FileMode.OpenOrCreate, FileAccess.Write))
            {
               EncodeSingleFile(inStream, outStream);
            }
         }
      }

      /// <summary>
      /// Encodes a single file. <paramref name="inStream"/> is the non-encoded
      /// file which will be encoded and placed into <paramref name="outStream"/>.
      /// If <paramref name="outStream"/> does not exist, it will be created.
      /// </summary>
      /// <param name="inStream">The in stream.</param>
      /// <param name="outStream">The out stream.</param>
      public override void EncodeSingleFile(FileStream inStream, FileStream outStream)
      {
         CoderPropID[] propIDs;
         object[] properties;
         LzmaEngine.PrepareEncoder(out propIDs, out properties);

         Encoder encoder = new Encoder();
         encoder.SetCoderProperties(propIDs, properties);
         encoder.WriteCoderProperties(outStream);
         Int64 fileSize = inStream.Length;
         for (int i = 0; i < 8; i++)
         {
            outStream.WriteByte((Byte) (fileSize >> (8*i)));
         }
         encoder.Code(inStream, outStream, -1, -1, null);
      }
   }
}